package raft

//
// this is an outline of the API that raft must expose to
// the service (or tester). see comments below for
// each of these functions for more details.
//
// rf = Make(...)
//   create a new Raft server.
// rf.Start(command interface{}) (index, Term, isleader)
//   start agreement on a new log entry
// rf.GetState() (Term, isLeader)
//   ask a Raft for its current Term, and whether it thinks it is leader
// ApplyMsg
//   each time a new entry is committed to the log, each Raft peer
//   should send an ApplyMsg to the service (or tester)
//   in the same server.
//

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)
import "labrpc"

// import "bytes"
// import "labgob"

const(
	MaxLockDuration=time.Duration(10*time.Millisecond)
)


//
// as each Raft peer becomes aware that successive log entries are
// committed, the peer should send an ApplyMsg to the service (or
// tester) on the same server, via the applyCh passed to Make(). set
// CommandValid to true to indicate that the ApplyMsg contains a newly
// committed log entry.
//
// in Lab 3 you'll want to send other kinds of messages (e.g.,
// snapshots) on the applyCh; at that point you can add fields to
// ApplyMsg, but set CommandValid to false for these other uses.
//
type ApplyMsg struct {
	CommandValid bool
	Command      interface{}
	CommandIndex int
}
type Entry struct{

}

//
// A Go object implementing a single Raft peer.
//
type Raft struct {
	mu        sync.Mutex          // Lock to protect shared access to this peer's state
	peers     []*labrpc.ClientEnd // RPC end points of all peers
	persister *Persister          // Object to hold this peer's persisted state
	me        int                 // this peer's index into peers[]

	// Your data here (2A, 2B, 2C).
	// Look at the paper's Figure 2 for a description of what
	// state a Raft server must maintain.

	//configure as <raft extended> figure2
	currentTerm int
	//map[Term]votefor
	votedFor map[int]int
	log []Entry

	commitIndex int
	lastApplied int
	nextIndex []int
	matchIndex []int


	timeContext *TimeAbout
	//
	isLeader bool
	state ServerStatus

	//time about
	heart *time.Timer
	elec_timer *time.Timer
	election_timeout time.Duration
	heart_tick time.Duration
	heart_timer_initial bool
	heart_begin time.Time


	//lock about
	lockName string
	lockTick time.Time

	terminateCh chan bool
}
/**
wrap concurrency control machanism
 */
func (rf *Raft) lock(lockName string){
	rf.mu.Lock()
	rf.lockName = lockName
	rf.lockTick = time.Now()

}
func (rf *Raft) unlock(lockName string){
	if(time.Since(rf.lockTick)>MaxLockDuration){
		fmt.Printf("[%d]lock:%s too much time!",rf.me,rf.lockName)
		rf.Kill()
	}
	rf.lockName = ""
	rf.mu.Unlock()
}

// return currentTerm and whether this server
// believes it is the leader.
func (rf *Raft) GetState() (int, bool) {
	var term int
	var isleader bool
	// Your code here (2A).
	rf.lock("GetState")
	term = rf.currentTerm
	isleader = rf.state==Leader
	rf.unlock("GetState")


	return term, isleader
}


//
// save Raft's persistent state to stable storage,
// where it can later be retrieved after a crash and restart.
// see paper's Figure 2 for a description of what should be persistent.
//
func (rf *Raft) persist() {
	// Your code here (2C).
	// Example:
	// w := new(bytes.Buffer)
	// e := labgob.NewEncoder(w)
	// e.Encode(rf.xxx)
	// e.Encode(rf.yyy)
	// data := w.Bytes()
	// rf.persister.SaveRaftState(data)
}


//
// restore previously persisted state.
//
func (rf *Raft) readPersist(data []byte) {
	if data == nil || len(data) < 1 { // bootstrap without any state?
		return
	}
	// Your code here (2C).
	// Example:
	// r := bytes.NewBuffer(data)
	// d := labgob.NewDecoder(r)
	// var xxx
	// var yyy
	// if d.Decode(&xxx) != nil ||
	//    d.Decode(&yyy) != nil {
	//   error...
	// } else {
	//   rf.xxx = xxx
	//   rf.yyy = yyy
	// }
}


type AppendEntryArgs struct {
	// Your data here (2A, 2B).
	Term         int
	CandidatId   int
	LastLogIndex int
	LastLogTerm  int
}

type AppendEntryReply struct {
	// Your data here (2A).
	Term        int
	VoteGranted bool
}

//
// example RequestVote RPC arguments structure.
// field names must start with capital letters!
//
type RequestVoteArgs struct {
	// Your data here (2A, 2B).
	Term         int
	CandidatId   int
	LastLogIndex int
	LastLogTerm  int
}
// server status enumeration
type ServerStatus string
const(
	Candidate ServerStatus="Candidate"
	Follower = "Follower"
	Leader = "Leader"
)

//
// example RequestVote RPC reply structure.
// field names must start with capital letters!
//
type RequestVoteReply struct {
	// Your data here (2A).
	Term        int
	VoteGranted bool
}

//
// example RequestVote RPC handler.
//
func (rf *Raft) RequestVote(args *RequestVoteArgs, reply *RequestVoteReply) {
	// Your code here (2A, 2B).
	rf.mu.Lock()
	_,ok:=rf.votedFor[args.Term]
	var log string
	//log+=fmt.Sprintf("======On Receive RequestVote,[%d->%d]======\n",args.CandidatId,rf.me)
	log+=fmt.Sprintf("%d receive requestVote RPC,args:{ID:%d,Term:%d}\n",rf.me,args.CandidatId,args.Term)
	if ok{
		//has voted this Term,return false
		reply.Term = rf.currentTerm
		reply.VoteGranted = false
		//log+=fmt.Sprintf("%d has already voted in Term:%d!,[%d->%d],Rejected\n",rf.me,args.Term,rf.me,voted_id)
	}else {
		if args.Term > rf.currentTerm {
			//log+=fmt.Sprintf("Encounter a higher Term,become a follower!\n")
			rf.state = Follower
			rf.currentTerm = args.Term
			reply.Term = rf.currentTerm
			reply.VoteGranted = true
			rf.votedFor[args.Term] = args.CandidatId
		} else if args.Term < rf.currentTerm {
			//log+=fmt.Sprintf("Encounter a lower Term!Rejected\n")
			reply.Term = rf.currentTerm
			reply.VoteGranted = false
		} else {
			//the same Term
			reply.Term = rf.currentTerm
			reply.VoteGranted = true
			rf.votedFor[args.Term] = args.CandidatId
			//log+=fmt.Sprintf("Sent a Vote[%d->%d]\n",rf.me,args.CandidatId)
		}
	}
	reply.Term = rf.currentTerm
	rf.mu.Unlock()
	log+=fmt.Sprintf("======RequestVote Finished,[%d->%d],arg:{Candi:%d,Term:%d}Result:{Term:%d,VoteGranted:%v}======\n",args.CandidatId,rf.me,args.CandidatId,args.Term,reply.Term,reply.VoteGranted)
	fmt.Println(log)


	return
}


//
// example RequestVote RPC handler.
//
func (rf *Raft) AppendEntry(args *AppendEntryArgs, reply *AppendEntryReply) {
	// Your code here (2A, 2B).
	rf.mu.Lock()
	//voted_id,ok:=rf.votedFor[args.Term]
	//var log string
	//log+=fmt.Sprintf("======On Receive RequestVote,[%d->%d]======\n",args.CandidatId,rf.me)
	//log+=fmt.Sprintf("%d receive requestVote RPC,args:{ID:%d,Term:%d}\n",rf.me,args.CandidatId,args.Term)
	//if ok{
	//	//has voted this Term,return false
	//	reply.VoteGranted = false
	//	log+=fmt.Sprintf("%d has already voted in Term:%d!,[%d->%d],Rejected\n",rf.me,args.Term,rf.me,voted_id)
	//}else {
	//	if args.Term > rf.currentTerm {
	//		log+=fmt.Sprintf("Encounter a higher Term!\n")
	//		reply.VoteGranted = true
	//		rf.votedFor[args.Term] = args.CandidatId
	//	} else if args.Term < rf.currentTerm {
	//		log+=fmt.Sprintf("Encounter a lower Term!Rejected\n")
	//		reply.VoteGranted = false
	//	} else {
	//		//the same Term
	//		reply.VoteGranted = true
	//		rf.votedFor[args.Term] = args.CandidatId
	//		log+=fmt.Sprintf("Sent a Vote[%d->%d]\n",rf.me,args.CandidatId)
	//	}
	//}
	//refuse stale leader
	reply.Term = rf.currentTerm

	if args.Term<rf.currentTerm{
		return
	}
	if args.Term>rf.currentTerm{
		rf.currentTerm = args.Term
		//add 2012-03-19 15:31
		rf.state = Follower
	}
	timeContext := rf.timeContext
	timeContext.mu.Lock()
	ok:=rf.timeContext.elec_timer.Reset(timeContext.elec_interval)//
	if !ok{
		Log(DebugL,"[%v][Reset Election Timer Failed],{ID:%d,Term:%d}\n",getCurTimeStamp(),rf.me,rf.currentTerm)
	}
	if args.CandidatId==rf.me{
		Log(DebugL,"[%v][Stop One Self From New Election],{ID:%d,Term:%d}\n",getCurTimeStamp(),rf.me,rf.currentTerm)
	}
	timeContext.mu.Unlock()

	rf.mu.Unlock()
	//log+=fmt.Sprintf("======Reset Election Timer,[%d->%d],Result:%v======\n",args.CandidatId,rf.me,ok)
	//fmt.Println(log)

	//reply.Term = rf.currentTerm
	return
}

//
// example code to send a RequestVote RPC to a server.
// server is the index of the target server in rf.peers[].
// expects RPC arguments in args.
// fills in *reply with RPC reply, so caller should
// pass &reply.
// the types of the args and reply passed to Call() must be
// the same as the types of the arguments declared in the
// handler function (including whether they are pointers).
//
// The labrpc package simulates a lossy network, in which servers
// may be unreachable, and in which requests and replies may be lost.
// Call() sends a request and waits for a reply. If a reply arrives
// within a timeout interval, Call() returns true; otherwise
// Call() returns false. Thus Call() may not return for a while.
// A false return can be caused by a dead server, a live server that
// can't be reached, a lost request, or a lost reply.
//
// Call() is guaranteed to return (perhaps after a delay) *except* if the
// handler function on the server side does not return.  Thus there
// is no need to implement your own timeouts around Call().
//
// look at the comments in ../labrpc/labrpc.go for more details.
//
// if you're having trouble getting RPC to work, check that you've
// capitalized all field names in structs passed over RPC, and
// that the caller passes the address of the reply struct with &, not
// the struct itself.
//
func (rf *Raft) sendRequestVote(server int, args *RequestVoteArgs, reply *RequestVoteReply) bool {
	//fmt.Printf("Send Request:peers,%d,server:%d\n",len(rf.peers),server)
	ok := rf.peers[server].Call("Raft.RequestVote", args, reply)
	return ok
}

func (rf *Raft) sendAppendEntry(server int, args *AppendEntryArgs, reply *AppendEntryReply) bool {
	//fmt.Printf("Send Request:peers,%d,server:%d\n",len(rf.peers),server)
	ok := rf.peers[server].Call("Raft.AppendEntry", args, reply)
	return ok
}


//
// the service using Raft (e.g. a k/v server) wants to start
// agreement on the next command to be appended to Raft's log. if this
// server isn't the leader, returns false. otherwise start the
// agreement and return immediately. there is no guarantee that this
// command will ever be committed to the Raft log, since the leader
// may fail or lose an election. even if the Raft instance has been killed,
// this function should return gracefully.
//
// the first return value is the index that the command will appear at
// if it's ever committed. the second return value is the current
// Term. the third return value is true if this server believes it is
// the leader.
//
func (rf *Raft) Start(command interface{}) (int, int, bool) {
	index := -1
	term := -1
	isLeader := true

	// Your code here (2B).


	return index, term, isLeader
}

//
// the tester calls Kill() when a Raft instance won't
// be needed again. you are not required to do anything
// in Kill(), but it might be convenient to (for example)
// turn off debug output from this instance.
//
func (rf *Raft) Kill() {
	// Your code here, if desired.
}
func getCurTimeStamp() string {
	timeStamp:=time.Now().Format("2006-01-02 15:04:05.000")
	return timeStamp
}
func (rf *Raft) resetElectionTimer() {
	rf.timeContext.elec_timer.Stop()
	rf.timeContext.elec_timer.Reset(rf.timeContext.elec_interval)
}
//
// the service or tester wants to create a Raft server. the ports
// of all the Raft servers (including this one) are in peers[]. this
// server's port is peers[me]. all the servers' peers[] arrays
// have the same order. persister is a place for this server to
// save its persistent state, and also initially holds the most
// recent saved state, if any. applyCh is a channel on which the
// tester or service expects Raft to send ApplyMsg messages.
// Make() must return quickly, so it should start goroutines
// for any long-running work.
//

func Serve(rf *Raft){


	//--------Part of My Code--------Main Function:EventLoop and Message Queue
	//eventChan := make(chan Event)

	//wrapper of timeContext
	timeContext := &TimeAbout{}
	timeContext.elec_interval = time.Duration(150+rand.Intn(150000)%100)*time.Millisecond	//election timeout 150-300 millisecond
	Log(DebugL,"[Set Election Timer],{ID:%d,tick:%d}\n",rf.me,timeContext.elec_interval)
	timeContext.elec_timer = time.NewTimer(timeContext.elec_interval)

	timeContext.heart_interval = time.Duration(100)*time.Millisecond							//lab2 assume that there is 10 heartbeats per second
	//var heart_beat_timer time.Timer
	heart_beat_timer := time.NewTimer(time.Hour)
	timeContext.heart_timer = heart_beat_timer
	timeContext.heart_initial = false
	timeContext.RPCTimeout = time.Duration(10)*time.Millisecond
	rf.timeContext = timeContext

	//Selection
	go func(){
		for{
			select{
			case <-rf.terminateCh:
				return
			case <-timeContext.elec_timer.C:
				tryElection3(rf)

			}
		}}()

	//AppendEntry
	go func(){
		for{
			select{
			case <-rf.terminateCh:
				return
			case <-timeContext.heart_timer.C:
				rf.mu.Lock()
				invalid_flag :=false
				if rf.state!=Leader {
					invalid_flag = true
				}
				Log(DebugL,"[%v][SendHeartBeat],{ID:%d,Term:%d,State:%s}\n",getCurTimeStamp(),rf.me,rf.currentTerm,rf.state)
				//rf.mu.Unlock()
				timeContext.mu.Lock()
				if invalid_flag {
					timeContext.heart_timer.Stop()
					Log(DebugL,"[%v][Stop Heart Beat Timer],{ID:%d,Term:%d,State:%s}\n",getCurTimeStamp(),rf.me,rf.currentTerm,rf.state)

				}else{
					ok:=timeContext.heart_timer.Reset(timeContext.heart_interval)
					//used like setTimeout,reset a timer after it is fired,so begin is safe in currency
					if ok{
						fmt.Printf("[%v],%d Reset Heart timer,result:%v\n",getCurTimeStamp(),rf.me,ok)
					}
					go SendHeartBeat1(rf)
				}


				timeContext.mu.Unlock()
				rf.mu.Unlock()
			}
		}
	}()
}
//struct about time
type TimeAbout struct {
	mu sync.Mutex
	format string
	elec_timer *time.Timer
	heart_timer *time.Timer
	elec_interval time.Duration
	heart_interval time.Duration
	RPCTimeout time.Duration

	prev_elec_tick time.Time
	prev_heart_tick time.Time
	heart_initial bool
}
type RequestVote struct{
	reply *RequestVoteReply

}
/**
 Try Election 3
 */
func tryElection3(rf *Raft){
	rf.lock("Start Election")
	rf.timeContext.elec_timer.Reset(rf.timeContext.elec_interval)

	rf.state = Candidate
	rf.currentTerm = rf.currentTerm+1 	//add currentTerm By 1
	var rawTerm = rf.currentTerm
	var peerCount = len(rf.peers)
	rf.unlock("Start Election")


	var elec_mu sync.Mutex
	var accept = 1
	var finished = 1
	var accessed=[]int{}
	var abortFlag = false

	request:=& RequestVoteArgs{CandidatId: rf.me, Term:rawTerm}

	replyChan:=make(chan *RequestVoteReply,peerCount)  	//buffered chanenl made it nonblock
	for i,_:=range rf.peers{							//check configuration,majority,not group
		if i==rf.me{
			continue									//vote for myself
		}
		go func(index int,rawTermArg int){
			reply:=& RequestVoteReply{}
			if rf.sendRequestVote(index,request,reply){	//only treat ok request
				elec_mu.Lock()
				accessed = append(accessed,index)
				elec_mu.Unlock()
				replyChan<-reply 						//decouple
			}
		}(i,rawTerm)
	}
	RPCTimer := time.NewTimer(rf.timeContext.RPCTimeout)//constant variable
	for{
		if abortFlag{
			break;										//break for loop
		}
		select{
		case reply:=<-replyChan:
			if reply.Term>rawTerm{						//if reply term > rf.curTerm,update rf self,abort
				rf.lock("reply term is higher than request argument")
				rf.state = Follower
				rf.currentTerm = reply.Term
				rf.resetElectionTimer()
				abortFlag = true
				rf.unlock("reply term is higher than request argument")
			}

			elec_mu.Lock()
			finished+=1
			if finished==peerCount{						//if all request has finished,abort wait
				abortFlag = true
			}
			if reply.VoteGranted{
				accept+=1
			}
			if accept>=peerCount/2+1{					//majority complished,abort
				abortFlag = true
			}
			elec_mu.Unlock()
		case <-RPCTimer.C:								//election transaction timeout,abort
			elec_mu.Lock()
			abortFlag = true
			elec_mu.Unlock()
		}
	}
	//treat detail
	if accept>=peerCount/2+1{
		rf.lock("majority complished")
		if rf.currentTerm != rawTerm{
			rf.state = Follower							//check info consistency
		}else{
			rf.state = Leader
			HeartBeatInitial(rf)			//send heart beat instantly
			go SendHeartBeat1(rf)
		}
		rf.unlock("majority complished")
	}
	elec_mu.Lock()

	elec_mu.Unlock()

	rf.mu.Lock()
	fmt.Printf("[%v][VoteSum]{ID:%dTerm:%d},Result:%v,Accessed:%v\n",getCurTimeStamp(),rf.me,rf.currentTerm,rf.state==Leader,accessed)
	rf.mu.Unlock()
}
/**
start a vote if elelction timer
*/
func tryElection2(rf *Raft,timeContext *TimeAbout){
	rf.mu.Lock()
	rf.state = Candidate
	rf.currentTerm = rf.currentTerm+1 	//add currentTerm By 1
	var rawTerm = rf.currentTerm
	var peerCount = len(rf.peers)
	rf.mu.Unlock()

	var elec_mu sync.Mutex
	var accept = 0
	var finished = 0
	var accessed=[]int{}
	var abortFlag = false

	replyChan:=make(chan *RequestVoteReply,peerCount)  //buffered chanenl made it nonblock
	for i,_:=range rf.peers{							//check configuration,majority,not group
		go func(index int,rawTermArg int){
			reply:=& RequestVoteReply{}
			request:=& RequestVoteArgs{CandidatId: rf.me, Term:rawTermArg}
			if rf.sendRequestVote(index,request,reply){
				elec_mu.Lock()
				accessed = append(accessed,index)
				elec_mu.Unlock()
				replyChan<-reply 						//decouple
			}
		}(i,rawTerm)
	}
	RPCTimer := time.NewTimer(timeContext.RPCTimeout)
	for{
		if abortFlag{
			break;										//break for loop
		}
		select{
			case reply:=<-replyChan:
				rf.mu.Lock()
				if reply.Term>rf.currentTerm{			//if reply term > rf.curTerm,update rf self,abort
					rf.state = Follower
					rf.currentTerm = reply.Term
					abortFlag = true
				}
				rf.mu.Unlock()

				elec_mu.Lock()
				finished+=1
				if finished==peerCount{					//if all request has finished,abort wait
					abortFlag = true
				}
				if reply.VoteGranted{					//change when needed
					accept+=1
				}
				if accept>=peerCount/2+1{
					abortFlag = true
				}
				elec_mu.Unlock()
			case <-RPCTimer.C:							//election transaction timeout
				elec_mu.Lock()
				abortFlag = true
				elec_mu.Unlock()
		}
	}
	//treat detail
	if accept>=peerCount/2+1{
		rf.mu.Lock()
		if rf.currentTerm != rawTerm{
			rf.state = Follower							//check info consistency
		}else{
			rf.state = Leader
			HeartBeatInitial(timeContext,rf.me)			//send heart beat instantly
			go SendHeartBeat1(rf)
		}
		rf.mu.Unlock()
	}
	rf.mu.Lock()
	elec_mu.Lock()
	fmt.Printf("[%v][VoteSum]{ID:%dTerm:%d},Result:%v,Accessed:%v\n",getCurTimeStamp(),rf.me,rf.currentTerm,rf.state==Leader,accessed)
	elec_mu.Unlock()
	rf.mu.Unlock()
}


/**
 start a vote if elelction timer
 */
//func tryElection1(rf *Raft,timeContext *TimeAbout){
//	//wait for majority
//	//var log string
//	rf.mu.Lock()
//	rf.state = Candidate
//	rf.currentTerm = rf.currentTerm+1 	//add currentTerm By 1
//	var rawTerm = rf.currentTerm
//	var cond = sync.NewCond(&rf.mu)
//	var accept = 0
//	var finished = 0
//	var abortFlag = false
//	supplier:=[]int{}
//	rf.mu.Unlock()
//
//
//	//for timeout detect
//
//	//RPCTimer := time.NewTimer(timeContext.RPCTimeout)
//
//
//
//	for i,_:=range rf.peers{			//check configuration,majority,not group
//		if abortFlag {
//			return
//		}
//		go func(index int,rawTermArg int){
//			reply:=& RequestVoteReply{}
//			request:=& RequestVoteArgs{CandidatId: rf.me, Term:rawTermArg}
//			//log+=fmt.Sprintf("Request Sent Start:[%d->%d]\n",rf.me,index) 	//index should be peers
//			rf.sendRequestVote(index,request,reply)
//			//block until RPC return
//			rf.mu.Lock()
//			finished+=1
//			//add in 2012-03-19
//			if reply.Term>rf.currentTerm{
//				rf.currentTerm = reply.Term
//				rf.state = Follower
//			}
//			if reply.VoteGranted == true{
//				supplier = append(supplier,index)
//				accept+=1
//			}else{
//				//log+=fmt.Sprintf("Request Vote Failed:[%d->%d]\n",rf.me,index)
//			}
//			//test if raft state has changed
//			if rawTermArg!=rf.currentTerm{
//				//log+=fmt.Sprintf("Term Changed:[%d->%d]\n",rf.me,index)
//				rf.mu.Unlock()
//				return
//			}
//			cond.Broadcast()
//			rf.mu.Unlock()
//		}(i,rawTerm)
//	}
//	rf.mu.Lock()
//	//fuck
//	for finished<len(rf.peers) && accept<len(rf.peers)/2+1{
//		//fmt.Printf("ID:%d,Vote Result:%d,finished:%d",rf.me,accept,finished)
//		cond.Wait()
//	}
//	rf.mu.Unlock()
//
//	select{
//
//
//	}
//
//
//	//log+=fmt.Sprintf("%d receive vote num:%d!\n",rf.me,accept)
//	rf.mu.Lock()
//	if accept>=len(rf.peers)/2+1{
//		//log+=fmt.Sprintf("%d was selected as leader!\n",rf.me)
//		rf.isLeader = true
//		rf.state = Leader
//
//		//TODO
//		HeartBeatInitial(timeContext,rf.me)
//		//send heart beat instantly
//		go SendHeartBeat(rf)
//
//	}else{
//		//log+=fmt.Sprintf("%d failed in vote!\n",rf.me)
//	}
//	fmt.Printf("[%v][VoteSum]{ID:%dTerm:%d},Result:%v,Supplier:%v\n",getCurTimeStamp(),rf.me,rf.currentTerm,rf.state==Leader,supplier)
//	rf.mu.Unlock()
//
//}
func tryElection1(rf *Raft,timeContext *TimeAbout){
	//wait for majority
	//var log string
	rf.mu.Lock()
	rf.state = Candidate
	rf.currentTerm = rf.currentTerm+1 	//add currentTerm By 1
	var rawTerm = rf.currentTerm
	var cond = sync.NewCond(&rf.mu)
	var accept = 0
	var finished = 0
	var abortFlag = false
	supplier:=[]int{}
	rf.mu.Unlock()
	for i,_:=range rf.peers{			//check configuration,majority,not group
		if abortFlag {
			return
		}
		go func(index int,rawTermArg int){
			reply:=& RequestVoteReply{}
			request:=& RequestVoteArgs{CandidatId: rf.me, Term:rawTermArg}
			//log+=fmt.Sprintf("Request Sent Start:[%d->%d]\n",rf.me,index) 	//index should be peers
			rf.sendRequestVote(index,request,reply)
			//block until RPC return
			rf.mu.Lock()
			finished+=1
			//add in 2012-03-19
			if reply.Term>rf.currentTerm{
				rf.currentTerm = reply.Term
				rf.state = Follower
			}
			if reply.VoteGranted == true{
				supplier = append(supplier,index)
				accept+=1
			}else{
				//log+=fmt.Sprintf("Request Vote Failed:[%d->%d]\n",rf.me,index)
			}
			//test if raft state has changed
			if rawTermArg!=rf.currentTerm{
				//log+=fmt.Sprintf("Term Changed:[%d->%d]\n",rf.me,index)
				rf.mu.Unlock()
				return
			}
			cond.Broadcast()
			rf.mu.Unlock()
		}(i,rawTerm)
	}
	rf.mu.Lock()
	//fuck
	for finished<len(rf.peers) && accept<len(rf.peers)/2+1{
		//fmt.Printf("ID:%d,Vote Result:%d,finished:%d",rf.me,accept,finished)
		cond.Wait()
	}
	rf.mu.Unlock()


	//log+=fmt.Sprintf("%d receive vote num:%d!\n",rf.me,accept)
	rf.mu.Lock()
	if accept>=len(rf.peers)/2+1{
		//log+=fmt.Sprintf("%d was selected as leader!\n",rf.me)
		rf.isLeader = true
		rf.state = Leader

		//TODO
		HeartBeatInitial(timeContext,rf.me)
		//send heart beat instantly
		go SendHeartBeat(rf)

	}else{
		//log+=fmt.Sprintf("%d failed in vote!\n",rf.me)
	}
	fmt.Printf("[%v][VoteSum]{ID:%dTerm:%d},Result:%v,Supplier:%v\n",getCurTimeStamp(),rf.me,rf.currentTerm,rf.state==Leader,supplier)
	rf.mu.Unlock()

}
func HeartBeatInitial(timeContext *TimeAbout,id int){
	timeContext.mu.Lock()
	if !timeContext.heart_initial{
		fmt.Printf("[%v],ID:%d,Heart Beat Initial\n",getCurTimeStamp(),id)
		//timeContext.heart_timer = time.NewTimer(timeContext.heart_interval)
		timeContext.heart_timer.Reset(timeContext.heart_interval)
	}
	timeContext.mu.Unlock()

}

func SendHeartBeat1(rf *Raft){
	rf.mu.Lock()
	var peerCount = len(rf.peers)
	rf.mu.Unlock()

	var ae_mu sync.Mutex
	var finished = 0
	var abortFlag = false
	var accessed=[]int{}

	request:=&  AppendEntryArgs{CandidatId: rf.me, Term:rf.currentTerm}
	replyChan:=make(chan *AppendEntryReply,peerCount)  //buffered chanenl made it nonblock
	for i,_:=range rf.peers{							//check configuration,majority,not group
		go func(index int){
			reply:=& AppendEntryReply{}
			rf.sendAppendEntry(index,request,reply)
			if rf.sendAppendEntry(index,request,reply){
				ae_mu.Lock()
				accessed = append(accessed,index)
				ae_mu.Unlock()
				replyChan<-reply 						//decouple
			}
		}(i)
	}
	RPCTimer := time.NewTimer(time.Duration(10)*time.Millisecond)
	for{
		if abortFlag{
			break;										//break for loop
		}
		select{
		case reply:=<-replyChan:
			rf.mu.Lock()
			if reply.Term>rf.currentTerm{			//if reply term > rf.curTerm,update rf self,abort
				rf.state = Follower
				//TODO
				rf.currentTerm = reply.Term
				abortFlag = true
			}
			rf.mu.Unlock()

			ae_mu.Lock()
			finished+=1
			if finished==peerCount{					//if all request has finished,abort wait
				abortFlag = true
			}
			ae_mu.Unlock()

		case <-RPCTimer.C:							//election transaction timeout
			ae_mu.Lock()
			abortFlag = true
			ae_mu.Unlock()
		}
	}
	rf.mu.Lock()
	ae_mu.Lock()
	fmt.Printf("[%v][Actual SendHeartBeat],{ID:%d,Term:%d},Accessed:%v\n",getCurTimeStamp(),rf.me,rf.currentTerm,accessed)
	ae_mu.Unlock()
	rf.mu.Unlock()
}


func SendHeartBeat(rf *Raft){
	rf.mu.Lock()
	rawTerm := rf.currentTerm
	Log(DebugL,"[%v][Actual SendHeartBeat],{ID:%d,Term:%d}\n",getCurTimeStamp(),rf.me,rf.currentTerm)
	rf.mu.Unlock()
	for i,_:=range rf.peers{
		go func(index int,rawTerm int){
			reply:=& AppendEntryReply{}
			// increase Term by 1
			request:=&  AppendEntryArgs{CandidatId: rf.me, Term:rf.currentTerm}
			//index should be peers
			//log+=fmt.Sprintf("AppendEntry RPC Sent Start:[%d->%d]\n",rf.me,index)
			rf.sendAppendEntry(index,request,reply)

			if reply.Term>rf.currentTerm{
				rf.mu.Lock()
				rf.currentTerm = reply.Term
				rf.state = Follower
				rf.mu.Unlock()
			}
			//if ok{
			//	if reply.VoteGranted == true{
			//		accept+=1
			//	}
			//}else{
			//	log+=fmt.Sprintf("Request Vote Failed:[%d->%d]\n",rf.me,index)
			//}
		}(i,rawTerm)
	}
}

//
// the service or tester wants to create a Raft server. the ports
// of all the Raft servers (including this one) are in peers[]. this
// server's port is peers[me]. all the servers' peers[] arrays
// have the same order. persister is a place for this server to
// save its persistent state, and also initially holds the most
// recent saved state, if any. applyCh is a channel on which the
// tester or service expects Raft to send ApplyMsg messages.
// Make() must return quickly, so it should start goroutines
// for any long-running work.
//
func Make(peers []*labrpc.ClientEnd, me int,
	persister *Persister, applyCh chan ApplyMsg) *Raft {
	rf := &Raft{}
	rf.peers = peers
	rf.persister = persister
	rf.me = me
	// Your initialization code here (2A, 2B, 2C).
	rf.votedFor=make(map[int]int)
	rf.state = Follower															// initialize FSM state
	rf.terminateCh = make(chan bool)
	go Serve(rf)
	// initialize from state persisted before a crash
	rf.readPersist(persister.ReadRaftState())
	return rf
}


	////chat with peers,send message
	//go func(){
	//	fmt.Printf("%d Raft Instance Started!\n",me)
	//	requestVoteChan:=make(chan string)
	//	begin:=time.Now()
	//	//1.wait a random time,start to send message to peers
	//
	//	//timer can adjust duration
	//
	//	elec_timer:=time.NewTimer(time.Duration(rand.Intn(10))*time.Millisecond)
	//	select{
	//		case <-elec_timer.C:
	//			fmt.Printf("")
	//			//true if timer is valid
	//			ok:=elec_timer.Reset(time.Duration(rand.Intn(10))*time.Millisecond)
	//			if ok {
	//				fmt.Printf("")
	//			}
	//			go func(){requestVoteChan<-"ready"}()
	//
	//		case <-requestVoteChan:
	//			//delta function SxV->S
	//			switch rf.state {
	//				case Candidate:
	//					fmt.Printf("election timeout,curState:{}",rf.state)
	//				case Follower:
	//					fmt.Printf("election timeout,curState:{}",rf.state)
	//				case Leader:
	//					fmt.Printf("election timeout,curState:{}",rf.state)
	//			}
	//
	//			// 2.send RequestVote to peers
	//
	//
	//
	//
	//	}
	//
	//	time.Sleep(time.Duration(rand.Intn(10))*time.Millisecond)
	//	fmt.Printf("group size:%d,raft index:%d,random initial election timeout:%s,start contact with others\n",len(peers),me,time.Since(begin))
	//	//use keyword go to avoid block
	//	//go func(){requestVoteChan<-"1"}()
	//	//<-requestVoteChan
	//	//2.send requestvote RPC to other peers
	//	var wg sync.WaitGroup
	//	var accept = 0

	//closure effected



	//for{
	//	begin:=time.Now()
	//	select{
	//		//1.wait a random time,start to send message to peers
	//		case <-time.After(time.Duration(rand.Intn(100))*time.Millisecond):
	//			fmt.Printf("group size:%d,raft index:%d,random initial election timeout:%s,start contact with others\n",len(peers),me,time.Since(begin))
	//			//use keyword go to avoid block
	//			go func(){requestVoteChan<-"1"}()
	//		case <-requestVoteChan:
	//			//2.send requestvote RPC to other peers
	//			var wg sync.WaitGroup
	//			var accept = 0
	//
	//
	//			for i,_:=range rf.peers{
	//				wg.Add(1)
	//				go func(){
	//					reply:=& RequestVoteReply{}
	//					request:=& RequestVoteArgs{Id:rf.me,Term: rf.Term,Offset:0}
	//					//index should be peers
	//					ok:=rf.sendRequestVote(i ,request,reply)
	//					if ok{
	//						wg.Done()
	//						if reply.Accept == true{
	//							accept+=1
	//						}
	//					}else{
	//						fmt.Printf("Request Vote Failed:[%d->%d]\n",rf.me,i)
	//					}
	//				}()
	//			}
	//			wg.Wait()
	//			if accept>len(peers)/2+1{
	//				fmt.Printf("%d was selected as leader!\n",me)
	//			}
	//	}
	//}

	//}()





func Makea(peers []*labrpc.ClientEnd, me int,
	persister *Persister, applyCh chan ApplyMsg) *Raft {
	rf := &Raft{}
	rf.peers = peers
	rf.persister = persister
	rf.me = me
	// Your initialization code here (2A, 2B, 2C).
	rf.votedFor=make(map[int]int)
	rf.state = Follower															// initialize FSM state

	// initialize from state persisted before a crash time.
	rf.readPersist(persister.ReadRaftState())
	//Main Function:EventLoop and Message Queue


	eventChan := make(chan Event)





	rf.election_timeout = time.Duration(150+rand.Intn(150))*time.Millisecond	//election timeout 150-300 millisecond
	begin := time.Now()
	elec_timer:=time.NewTimer(rf.election_timeout)
	rf.elec_timer = elec_timer

	rf.heart_tick = time.Duration(100)*time.Millisecond							//lab2 assume that there is 10 heartbeats per second
	rf.heart_timer_initial = false
	var heart_beat_timer time.Timer
	rf.heart = &heart_beat_timer


	//rfheart_begin := time.Now()
	go func(){
		for{
			select{
			case <-elec_timer.C:
				//true if timer is not fired
				go func(start_stamp time.Time){
					rf.mu.Lock()
					Log(DebugL,"[Timer Expired],ID:%d,election timeout:%s,Term:%d,timer:%v,begin:%v->end:%v\n",rf.me,time.Since(start_stamp),rf.currentTerm,rf.election_timeout,begin,time.Now())
					ok:=elec_timer.Reset(rf.election_timeout)

					begin = time.Now()
					rf.mu.Unlock()

					//used like setTimeout,reset a timer after it is fired,so begin is safe in currency
					if ok{
						fmt.Printf("%d Reset election timer without fired\n",me)
					}
					go func(){eventChan<-Event{etype:ElectionTimeout}}()
				}(begin)
			case <-rf.heart.C:
				rf.mu.Lock()
				Log(DebugL,"[HeartBeat Timer Expired],ID:%d,election timeout:%s,Term:%d,timer:%v,begin:%v->end:%v\n",rf.me,time.Since(rf.heart_begin),rf.currentTerm,rf.heart_tick,rf.heart_begin,time.Now())
				go func(){
					eventChan<-Event{etype:HeartBeat}
				}()
				rf.heart_begin =time.Now()
				ok:=rf.heart.Reset(rf.heart_tick)
				rf.mu.Unlock()
				if ok{
					fmt.Printf("%d Reset heart ticker without fired\n",me)
				}
			case event:=<-eventChan:
				go FSM_delta_function(rf,event,eventChan)
			}
		}}()

	////chat with peers,send message
	//go func(){
	//	fmt.Printf("%d Raft Instance Started!\n",me)
	//	requestVoteChan:=make(chan string)
	//	begin:=time.Now()
	//	//1.wait a random time,start to send message to peers
	//
	//	//timer can adjust duration
	//
	//	elec_timer:=time.NewTimer(time.Duration(rand.Intn(10))*time.Millisecond)
	//	select{
	//		case <-elec_timer.C:
	//			fmt.Printf("")
	//			//true if timer is valid
	//			ok:=elec_timer.Reset(time.Duration(rand.Intn(10))*time.Millisecond)
	//			if ok {
	//				fmt.Printf("")
	//			}
	//			go func(){requestVoteChan<-"ready"}()
	//
	//		case <-requestVoteChan:
	//			//delta function SxV->S
	//			switch rf.state {
	//				case Candidate:
	//					fmt.Printf("election timeout,curState:{}",rf.state)
	//				case Follower:
	//					fmt.Printf("election timeout,curState:{}",rf.state)
	//				case Leader:
	//					fmt.Printf("election timeout,curState:{}",rf.state)
	//			}
	//
	//			// 2.send RequestVote to peers
	//
	//
	//
	//
	//	}
	//
	//	time.Sleep(time.Duration(rand.Intn(10))*time.Millisecond)
	//	fmt.Printf("group size:%d,raft index:%d,random initial election timeout:%s,start contact with others\n",len(peers),me,time.Since(begin))
	//	//use keyword go to avoid block
	//	//go func(){requestVoteChan<-"1"}()
	//	//<-requestVoteChan
	//	//2.send requestvote RPC to other peers
	//	var wg sync.WaitGroup
	//	var accept = 0

	//closure effected



	//for{
	//	begin:=time.Now()
	//	select{
	//		//1.wait a random time,start to send message to peers
	//		case <-time.After(time.Duration(rand.Intn(100))*time.Millisecond):
	//			fmt.Printf("group size:%d,raft index:%d,random initial election timeout:%s,start contact with others\n",len(peers),me,time.Since(begin))
	//			//use keyword go to avoid block
	//			go func(){requestVoteChan<-"1"}()
	//		case <-requestVoteChan:
	//			//2.send requestvote RPC to other peers
	//			var wg sync.WaitGroup
	//			var accept = 0
	//
	//
	//			for i,_:=range rf.peers{
	//				wg.Add(1)
	//				go func(){
	//					reply:=& RequestVoteReply{}
	//					request:=& RequestVoteArgs{Id:rf.me,Term: rf.Term,Offset:0}
	//					//index should be peers
	//					ok:=rf.sendRequestVote(i ,request,reply)
	//					if ok{
	//						wg.Done()
	//						if reply.Accept == true{
	//							accept+=1
	//						}
	//					}else{
	//						fmt.Printf("Request Vote Failed:[%d->%d]\n",rf.me,i)
	//					}
	//				}()
	//			}
	//			wg.Wait()
	//			if accept>len(peers)/2+1{
	//				fmt.Printf("%d was selected as leader!\n",me)
	//			}
	//	}
	//}

	//}()
	return rf
}
//func startElec
func tryElection(rf *Raft,eventChan chan Event){
	//wait for majority
	var log string
	rf.mu.Lock()
	rf.state = Candidate
	rf.currentTerm = rf.currentTerm+1 	//add currentTerm By 1
	var rawTerm = rf.currentTerm
	var cond = sync.NewCond(&rf.mu)
	var accept = 0
	var finished = 0
	var abortFlag = false
	rf.mu.Unlock()
	for i,_:=range rf.peers{			//check configuration,majority,not group
		if abortFlag {
			return
		}
		go func(index int){
			reply:=& RequestVoteReply{}
			request:=& RequestVoteArgs{CandidatId: rf.me, Term:rf.currentTerm}
			log+=fmt.Sprintf("Request Sent Start:[%d->%d]\n",rf.me,index) 	//index should be peers
			rf.sendRequestVote(index,request,reply)
			//block until RPC return
			rf.mu.Lock()
			finished+=1
			if reply.VoteGranted == true{
				accept+=1
			}else{
				log+=fmt.Sprintf("Request Vote Failed:[%d->%d]\n",rf.me,index)
			}
			//test if raft state has changed
			if rawTerm!=rf.currentTerm{
				log+=fmt.Sprintf("Term Changed:[%d->%d]\n",rf.me,index)
				return
			}
			cond.Broadcast()
			rf.mu.Unlock()
		}(i)
	}
	rf.mu.Lock()
	//fuck
	for finished<len(rf.peers) && accept<len(rf.peers)/2+1{
		fmt.Printf("ID:%d,Vote Result:%d,finished:%d",rf.me,accept,finished)
		cond.Wait()
	}
	rf.mu.Unlock()
	log+=fmt.Sprintf("%d receive vote num:%d!\n",rf.me,accept)
	if accept>=len(rf.peers)/2+1{
		log+=fmt.Sprintf("%d was selected as leader!\n",rf.me)
		rf.isLeader = true
		rf.state = Leader
		go func(){eventChan<-Event{etype:ElectedAsLeader}}()
	}else{
		log+=fmt.Sprintf("%d failed in vote!\n",rf.me)
	}
	fmt.Println(log)


}


func MakePrev(peers []*labrpc.ClientEnd, me int,
	persister *Persister, applyCh chan ApplyMsg) *Raft {
	rf := &Raft{}
	rf.peers = peers
	rf.persister = persister
	rf.me = me

	// Your initialization code here (2A, 2B, 2C).
	rf.votedFor=make(map[int]int)
	// initialize FSM state
	rf.state = Follower
	rf.election_timeout = time.Duration(10+rand.Intn(10))
	rf.heart_tick = time.Duration(5)
	// initialize from state persisted before a crash time.
	rf.readPersist(persister.ReadRaftState())

	//EventLoop and Message Queue
	go func(){
		eventChan := make(chan Event)

	elec_timer:=time.NewTimer(time.Duration(10+rand.Intn(10))*time.Millisecond)
	//interval
	//heart_beaat_timer:= time.NewTimer(time.Duration(10)*time.Millisecond)
	var heart_beat_timer time.Timer
	rf.heart = &heart_beat_timer
	rf.elec_timer = elec_timer
	rf.heart_timer_initial = false
	begin := time.Now()
	for{
		select{
			case <-elec_timer.C:
				//true if timer is not fired
				go func(){
					eventChan<-Event{etype:ElectionTimeout}
					fmt.Printf("[Timer Expired],ID:%d,election timeout:%s,Term:%d\n",rf.me,time.Since(begin),rf.currentTerm)
					ok:=elec_timer.Reset(time.Duration(10+rand.Intn(10))*time.Millisecond)
					begin = time.Now()
					if ok{
						fmt.Printf("%d Reset election timer without fired\n",me)
					}
				}()
			case <-rf.heart.C:
				go func(){
					eventChan<-Event{etype:HeartBeat}
				}()
			case event:=<-eventChan:
				go FSM_delta_function(rf,event,eventChan)
		}
	}}()

	////chat with peers,send message
	//go func(){
	//	fmt.Printf("%d Raft Instance Started!\n",me)
	//	requestVoteChan:=make(chan string)
	//	begin:=time.Now()
	//	//1.wait a random time,start to send message to peers
	//
	//	//timer can adjust duration
	//
	//	elec_timer:=time.NewTimer(time.Duration(rand.Intn(10))*time.Millisecond)
	//	select{
	//		case <-elec_timer.C:
	//			fmt.Printf("")
	//			//true if timer is valid
	//			ok:=elec_timer.Reset(time.Duration(rand.Intn(10))*time.Millisecond)
	//			if ok {
	//				fmt.Printf("")
	//			}
	//			go func(){requestVoteChan<-"ready"}()
	//
	//		case <-requestVoteChan:
	//			//delta function SxV->S
	//			switch rf.state {
	//				case Candidate:
	//					fmt.Printf("election timeout,curState:{}",rf.state)
	//				case Follower:
	//					fmt.Printf("election timeout,curState:{}",rf.state)
	//				case Leader:
	//					fmt.Printf("election timeout,curState:{}",rf.state)
	//			}
	//
	//			// 2.send RequestVote to peers
	//
	//
	//
	//
	//	}
	//
	//	time.Sleep(time.Duration(rand.Intn(10))*time.Millisecond)
	//	fmt.Printf("group size:%d,raft index:%d,random initial election timeout:%s,start contact with others\n",len(peers),me,time.Since(begin))
	//	//use keyword go to avoid block
	//	//go func(){requestVoteChan<-"1"}()
	//	//<-requestVoteChan
	//	//2.send requestvote RPC to other peers
	//	var wg sync.WaitGroup
	//	var accept = 0

		//closure effected



		//for{
		//	begin:=time.Now()
		//	select{
		//		//1.wait a random time,start to send message to peers
		//		case <-time.After(time.Duration(rand.Intn(100))*time.Millisecond):
		//			fmt.Printf("group size:%d,raft index:%d,random initial election timeout:%s,start contact with others\n",len(peers),me,time.Since(begin))
		//			//use keyword go to avoid block
		//			go func(){requestVoteChan<-"1"}()
		//		case <-requestVoteChan:
		//			//2.send requestvote RPC to other peers
		//			var wg sync.WaitGroup
		//			var accept = 0
		//
		//
		//			for i,_:=range rf.peers{
		//				wg.Add(1)
		//				go func(){
		//					reply:=& RequestVoteReply{}
		//					request:=& RequestVoteArgs{Id:rf.me,Term: rf.Term,Offset:0}
		//					//index should be peers
		//					ok:=rf.sendRequestVote(i ,request,reply)
		//					if ok{
		//						wg.Done()
		//						if reply.Accept == true{
		//							accept+=1
		//						}
		//					}else{
		//						fmt.Printf("Request Vote Failed:[%d->%d]\n",rf.me,i)
		//					}
		//				}()
		//			}
		//			wg.Wait()
		//			if accept>len(peers)/2+1{
		//				fmt.Printf("%d was selected as leader!\n",me)
		//			}
		//	}
		//}

	//}()
	return rf
}
//abstract FSM delta_function out SxV->S,follow paper Raft Extended
func FSM_delta_function(rf *Raft,event Event,eventChan chan Event){
	rf.mu.Lock()
	var log string
	cur_state :=rf.state
	log+=fmt.Sprintf("[FSM]ID:%d start FSM delta function,{%v}x%v\n",rf.me,cur_state,event)
	rf.mu.Unlock()
	switch rf.state {
	case Follower:
		switch event.etype{
		//1.start an election
		case ElectionTimeout:
			rf.state = Candidate
			//log+=fmt.Sprintf("%d,%vx%v->%v\n",rf.me,cur_state,event,rf.state)
			go func(){eventChan<-Event{etype:StartElect}}()
		}
	case Candidate:
		switch event.etype{
		//1.start an election
		case ElectionTimeout:
			//state remaain unchanged
			go func(){eventChan<-Event{etype:StartElect}}()
		case StartElect:
			tryElection(rf,eventChan)
			//log+=fmt.Sprintf("ID:%d %vx%v->%v\n",rf.me,cur_state,event,rf.state)
		}
	case Leader:
		switch event.etype{
		case "ElectionTimeout":
			rf.state = Candidate
			rf.heart.Stop()
			rf.heart_timer_initial = false
			go func(){eventChan<-Event{etype:StartElect}}()

		//1.start an election
		case StartElect:
			log+=fmt.Sprintf("election timeout,curState:%v\n",rf.state)
		case ElectedAsLeader:
			log+=fmt.Sprintf("Leader Elected,%d,%v\n",rf.me,rf.heart)
			log+=fmt.Sprintf("%d,%vx%v->%v\n",rf.me,cur_state,event,rf.state)

			if !rf.heart_timer_initial{
				//invoke heartbeat instantly
				log+=fmt.Sprintf("Leader Elected,trigger raft heart beat,%d\n",rf.me)
				rf.heart = time.NewTimer(rf.heart_tick)
				rf.heart_begin = time.Now()
				//
				go func(){eventChan<-Event{etype: HeartBeat}}()
			}
		case HeartBeat:
			// send AppendEntry RPC to peers heart beat
			for i,_:=range rf.peers{
				go func(index int){
					reply:=& AppendEntryReply{}
					// increase Term by 1
					request:=&  AppendEntryArgs{CandidatId: rf.me, Term:rf.currentTerm}
					//index should be peers
					log+=fmt.Sprintf("AppendEntry RPC Sent Start:[%d->%d]\n",rf.me,index)
					rf.sendAppendEntry(index,request,reply)
					//if ok{
					//	if reply.VoteGranted == true{
					//		accept+=1
					//	}
					//}else{
					//	log+=fmt.Sprintf("Request Vote Failed:[%d->%d]\n",rf.me,index)
					//}
				}(i)
			}
			//wg.Wait()
			//log+=fmt.Sprintf("%d receive vote num:%d!\n",rf.me,accept)
			//if accept>=len(rf.peers)/2+1{
			//	log+=fmt.Sprintf("%d was selected as leader!\n",rf.me)
			//	rf.isLeader = true
			//	rf.state = Leader
			//	go func(){eventChan<-Event{etype:ElectedAsLeader}}()
			//}else{
			//	log+=fmt.Sprintf("%d failed in vote!\n",rf.me)
			//}


			//pwd
		}

	}
	log+="----------------------delt function End-----------------------------\n"
	//rf.mu.Unlock()
	fmt.Println(log)
}


//func Make1(peers []*labrpc.ClientEnd, me int,
//	persister *Persister, applyCh chan ApplyMsg) *Raft {
//	rf := &Raft{}
//	rf.peers = peers
//	rf.persister = persister
//	rf.me = me
//
//	// Your initialization code here (2A, 2B, 2C).
//	rf.votedThisTem=make(map[int]int)
//
//
//	// initialize from state persisted before a crash
//	//time.
//	rf.readPersist(persister.ReadRaftState())
//
//	//chat with peers,send message
//	go func(){
//		fmt.Printf("%d Raft Instance Started!\n",me)
//		requestVoteChan:=make(chan string)
//		begin:=time.Now()
//		//1.wait a random time,start to send message to peers
//		<-time.After(time.Duration(rand.Intn(100))*time.Millisecond)
//		fmt.Printf("group size:%d,raft index:%d,random initial election timeout:%s,start contact with others\n",len(peers),me,time.Since(begin))
//		//use keyword go to avoid block
//		go func(){requestVoteChan<-"1"}()
//		<-requestVoteChan
//		//2.send requestvote RPC to other peers
//		var wg sync.WaitGroup
//		var accept = 0
//
//
//		for i,_:=range rf.peers{
//			wg.Add(1)
//			go func(){
//				reply:=& RequestVoteReply{}
//				request:=& RequestVoteArgs{Id:rf.me,Term: rf.Term,Offset:0}
//				//index should be peers
//				ok:=rf.sendRequestVote(i ,request,reply)
//				if ok{
//					wg.Done()
//					if reply.Accept == true{
//						accept+=1
//					}
//				}else{
//					fmt.Printf("Request Vote Failed:[%d->%d]\n",rf.me,i)
//				}
//			}()
//		}
//		wg.Wait()
//		if accept>len(peers)/2+1{
//			fmt.Printf("%d was selected as leader!\n",me)
//		}else{
//			fmt.Printf("%d failed in vote!\n",me)
//		}
//
//		//for{
//		//	begin:=time.Now()
//		//	select{
//		//		//1.wait a random time,start to send message to peers
//		//		case <-time.After(time.Duration(rand.Intn(100))*time.Millisecond):
//		//			fmt.Printf("group size:%d,raft index:%d,random initial election timeout:%s,start contact with others\n",len(peers),me,time.Since(begin))
//		//			//use keyword go to avoid block
//		//			go func(){requestVoteChan<-"1"}()
//		//		case <-requestVoteChan:
//		//			//2.send requestvote RPC to other peers
//		//			var wg sync.WaitGroup
//		//			var accept = 0
//		//
//		//
//		//			for i,_:=range rf.peers{
//		//				wg.Add(1)
//		//				go func(){
//		//					reply:=& RequestVoteReply{}
//		//					request:=& RequestVoteArgs{Id:rf.me,Term: rf.Term,Offset:0}
//		//					//index should be peers
//		//					ok:=rf.sendRequestVote(i ,request,reply)
//		//					if ok{
//		//						wg.Done()
//		//						if reply.Accept == true{
//		//							accept+=1
//		//						}
//		//					}else{
//		//						fmt.Printf("Request Vote Failed:[%d->%d]\n",rf.me,i)
//		//					}
//		//				}()
//		//			}
//		//			wg.Wait()
//		//			if accept>len(peers)/2+1{
//		//				fmt.Printf("%d was selected as leader!\n",me)
//		//			}
//		//	}
//		//}
//
//	}()
//	return rf
//}